<?php

require_once dirname(__file__) . "/../models/wxpay/lib/WxPay.Data.php";
require_once dirname(__file__) . "/../models/wxpay/lib/WxPay.Notify.php";
require_once dirname(__file__) . "/../models/wxpay/WxPay.NativePay.php";
require_once dirname(__file__) . "/../models/wxpay/WxPay.JsApiPay.php";

/**
 * 微信支付相关的控制器
 */
class PaymentController extends BaseController {
	
	protected $layout = 'layouts.master';
	
	public function index() {
		$this->layout->content = View::make ( 'errors.coming' );
	}

	public function generateQrCodeUrl($attach) {

		//模式二
		/**
		 * 流程：
		 * 1、调用统一下单，取得code_url，生成二维码
		 * 2、用户扫描二维码，进行支付
		 * 3、支付完成之后，微信服务器会通知支付成功
		 * 4、在支付成功通知中需要查单确认是否真正支付成功（见：notify.php）
		 */
	    $outTradeNo = WxPayConfig::MCHID.date("YmdHis");
		$nativePay = new NativePay();
		$input = new WxPayUnifiedOrder();
		$input->SetBody("律团支付");  												// 设置商品或支付单简要描述
		$input->SetAttach($attach);													// 设置附加数据，在查询API和支付通知中原样返回，该字段主要用于商户携带订单的自定义数据
		$input->SetOut_trade_no($outTradeNo);					                    // 设置商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
		$attachArr = json_decode($attach, true);
		$money = floatval($attachArr['money']);
		$money = round($money);
		$input->SetTotal_fee($money*100);
		$input->SetTime_start(date("YmdHis"));										// 设置订单生成时间
		$input->SetTime_expire(date("YmdHis", time() + 600));						// 设置订单失效时间
		$input->SetGoods_tag("test");												// 设置商品标记，代金券或立减优惠功能的参数，说明详见代金券或立减优惠
		$input->SetNotify_url(route('payment.notify'));								// 设置接收微信支付异步通知回调地址
		$input->SetTrade_type("NATIVE");											// 设置取值如下：JSAPI，NATIVE，APP，详细说明见参数规定
		if (isset($attachArr['item_id'])) {
			$input->SetProduct_id($attachArr['item_id']);								// 设置trade_type=NATIVE，此参数必传。此id为二维码中包含的商品ID，商户自行定义。
		} else {
			$input->SetProduct_id("wallet");
		}
		$result = $nativePay->GetPayUrl($input);
		return array('url'=>$result["code_url"], 'out_trade_no'=>$outTradeNo);
	}

	public function jsApiParameters($openid, $attach) {
		Log::info(__METHOD__ . __LINE__ . ' hitting jsApiParameters: ' . $openid);
		$input = new WxPayUnifiedOrder();
		$tools = new JsApiPay();
		$input->SetBody("律团支付");
		$input->SetAttach($attach);
		$input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));
		$attachArr = json_decode($attach, true);
		$money = floatval($attachArr['money']);
		$money = round($money);

		$input->SetTotal_fee($money*100);
		$input->SetTime_start(date("YmdHis"));
		$input->SetTime_expire(date("YmdHis", time() + 600));
		$input->SetGoods_tag("test");
		$input->SetNotify_url(route('payment.notify'));
		$input->SetTrade_type("JSAPI");
		$input->SetOpenid($openid);
		$order = WxPayApi::unifiedOrder($input);
		$jsApiParameters = $tools->GetJsApiParameters($order);
		Log::info(__METHOD__ . __LINE__ . ' hitting jsApiParameters: ' . json_encode($jsApiParameters));
		return $this->makeView('parameters.display', array('params' => json_decode($jsApiParameters, true)), 200);
	}

	public function displayQrCode() {
		$attach = ['type'=>'question', 'item_id'=>'2175', 'money'=>'1'];
		$attachStr = json_encode($attach);
		$result = $this->generateQrCodeUrl($attachStr);
		return $this->makeView('payment.display', $result, 200);
	}
	
	/**
	 * 生成咨询订单的二维码
	 */
	public function qrParams($attachStr) {
		$result = $this->generateQrCodeUrl($attachStr);
		return $this->makeView('payment.qr_params', $result, 200);
	}
	
	public function query($out_trade_no) {
	    $input = new WxPayOrderQuery();
	    $input->SetOut_trade_no($out_trade_no);
	    $result = WxPayApi::orderQuery($input);
	    Log::info(__METHOD__ . __LINE__ . " out_trade_no: " . $out_trade_no);
	    Log::info(__METHOD__ . __LINE__ . json_encode($result));
	    return $this->makeView('payment.query', $result, 200);
	}

	/**
	 * 微信支付的回调方法
	 */
	public function notify() {
		Log::info(__METHOD__ . ' hitting notify method after payment.' . json_encode($GLOBALS['HTTP_RAW_POST_DATA']));
		if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
            return $this->makeView(
                'errors.400', 
                array('post_data' => '提交的数据不能为空'),
                400
            );
		}

		// 处理从微信回调获取的数据
		$wxpayData = new WxPayDataBase();
		$values = $wxpayData->FromXml($GLOBALS['HTTP_RAW_POST_DATA']);
		$attach = json_decode($values['attach'], true);

		// 登录微信用户
		if (isset($values['openid'])) {
    		$user = User::where('wx_openid', $values['openid'])->first();
    		if ($user) {
    		  Auth::login($user);
    		}
		}

		// 钱包充值
		if ($attach['type'] == 'wallet_recharge') {
			// 如果传的值和实际的值不一样，则报错
			$attach_money = round($attach['money']);
			$total_fee = round($values['total_fee']/100);
			if ($attach_money == $total_fee) {
				$order_id = $values['out_trade_no'];
				// 看看订单是否已经存在
				$transaction = WalletTransaction::getWalletTransaction(
					$attach['user_id'], WalletTransaction::TYPE_RECHARGE, $order_id, WalletTransaction::DIRECTION_IN);
				if (!$transaction) {
					$message = "微信充值";
					$wallet = Wallet::getWallet($attach['user_id']);
					$wallet->recharge($attach['user_id'], $attach_money, $message, $order_id, "wx_pub_qr");
				}
			} else {
				Log::info(sprintf("支付金额不对%s, %s", $attach_money, $total_fee));
			}
		} if ($attach['type'] == 'wallet_reward') {
            $order_id = $values['out_trade_no'];
            // 看看订单是否已经存在
            $transaction = WalletTransaction::getWalletTransaction($attach['user_id'], 
                WalletTransaction::TYPE_REWARD, $order_id, WalletTransaction::DIRECTION_IN);
            if (! $transaction) {
                $from_user = User::find($attach['from_user_id']);
                $message = sprintf("收到用户%s,%s的心意", $from_user->id, $from_user->realname);
                $wallet = Wallet::getWallet($attach['user_id']);
                $wallet->reward($attach_money, $message, $order_id, $attach['user_id'], $attach['from_user_id']);
            }
		} else if (in_array($attach['type'], ['question','order'])) {
			$question_id = $attach['item_id'];
			$question = Post::find($question_id);
			$order = $question->getOrder($question_id);
			$associate_id = $values['out_trade_no'];
			try {
				$question->status = Post::STATUS_NEW;
				$question->save();
				$order->state = Order::STATE_PAID;
				$order->pay_status = Order::PAY_STATUS_PAIS;
				$order->associate_id = $associate_id;
				$order->save();
			} catch (Exception $ex) {
				Log::error($ex);
			}
		}

		$notify = new WxPayNotify();
		$notify->Handle(true);
	}

	public function success($out_trade_no) {
	    $input = new WxPayOrderQuery();
	    $input->SetOut_trade_no($out_trade_no);
	    $result = WxPayApi::orderQuery($input);
	    $attachStr = $result['attach'];
	    $attachArr = json_decode($attachStr, true);
	    $question = Post::find($attachArr['item_id']);
		$order = $question->getOrder($question->id);
		$orderArr = $order->toArray();
		$data = [];
		$data['order_no'] = $orderArr['order_no'];
		$data['title'] = $orderArr['title'];
		$data['updated_at'] = $orderArr['updated_at'];
		$data['price'] = round($orderArr['price']);
		$data['question_id'] = $question->id;
	    return $this->makeView('payment.success', $data, 200);
	}
}
